package com.davfx.restream;

import java.io.IOException;
import java.nio.ByteBuffer;

import com.davfx.httpnio.HttpResponse;
import com.davfx.httpnio.HttpServer;
import com.davfx.util.Log;

final class Player implements Runnable {
	private static final long INITIAL_DELTA = 200; // 200ms
	
	private final Runnable closeHandler;
	private final long from;
	private final HttpServer.Response response;
	private final DatabaseReader databaseReader;
	private long initTime;
	private boolean closed = false;
	
	public Player(Runnable closeHandler, Database database, long from, HttpServer.Response response) {
		this.closeHandler = closeHandler;
		databaseReader = database.getReader(from);
		this.from = from;
		this.response = response;
		
		try {
			HttpResponse r = databaseReader.getHttpResponse();
			if (r == null) {
				doClose(); //TODO verifier qu'on est CHUNKED
			} else {
				response.write(r);
				if (!databaseReader.next()) {
					doClose();
				} else {
					while (true) { //TODO to limit memory footprint, check response.canWrite
						long dt = databaseReader.getTime();
						if (dt >= (from + INITIAL_DELTA)) {
							break;
						}
						response.write(databaseReader.getBuffer());
						if (!databaseReader.next()) {
							doClose();
							break;
						}
					}
				}
		
				initTime = System.currentTimeMillis();
			}
		} catch (IOException e) {
			Log.error("Could not playback", e);
			doClose();
		}
	}
	
	private void doClose() {
		closed = true;
		databaseReader.close();
		response.close();
		closeHandler.run();
	}
	
	public void closed() {
		doClose();
	}
	
	@Override
	public void run() {
 		if (closed) {
			return;
		}
		
		long delta = System.currentTimeMillis() - initTime;

		try {
			while (true) { //TODO to limit memory footprint, check response.canWrite
				long dt = databaseReader.getTime();
				if (dt >= (from + delta)) {
					break;
				}
				ByteBuffer b = databaseReader.getBuffer();
				response.write(b);
				if (!databaseReader.next()) {
					doClose();
					break;
				}
			}
		} catch (IOException e) {
			Log.error("Could not playback", e);
			doClose();
		}
	}
}
